#include "qipan.h"

qipan::qipan(QWidget *parent) : QWidget(parent)
{
    setMouseTracking(true);
    m_isHoverFlag = true;

    for (int idx = 0; idx < m_boardSize; idx++)
    {
        for (int jdx = 0; jdx < m_boardSize; jdx++)
        {
            m_point[idx][jdx] = -1;
        }
    }
}

/* 绘图事件 */
void qipan::paintEvent(QPaintEvent * event)
{
    QPainter painter(this);

    /* 绘制棋盘颜色 */
    QColor backgroundColor(216, 181, 136);
    painter.fillRect(rect(), backgroundColor);

    /* 绘制网格线 */
    for (int idx = 0; idx < m_boardSize; idx++)
    {
        /* 绘制竖线 */
        painter.drawLine(m_margin + idx * m_cellSize, m_margin, m_margin + idx * m_cellSize, m_margin + (m_boardSize - 1) * m_cellSize);
        /* 绘制横线 */
        painter.drawLine(m_margin, m_margin + idx * m_cellSize, m_margin + (m_boardSize - 1) * m_cellSize, m_margin + idx * m_cellSize);
    }

    /* 绘制鼠标悬停的提示圆 */
    if (m_isHoverFlag == true && (m_hoverRow >= 0 && m_hoverRow < m_boardSize) && (m_hoverCol >= 0 && m_hoverCol < m_boardSize) && m_point[m_hoverRow][m_hoverCol] == 0)
    {
        painter.setBrush(Qt::red);
        painter.drawEllipse(m_margin + m_hoverRow * m_cellSize - m_cellSize / 6, m_margin + m_hoverCol * m_cellSize - m_cellSize / 6, m_cellSize / 3, m_cellSize / 3);
    }

    /* 绘制棋子 */
    for (int idx = 0; idx < m_boardSize; idx++)
    {
        for (int jdx = 0; jdx < m_boardSize; jdx++)
        {
            if (m_point[idx][jdx] == PLAYER)
            {
                /* 玩家 */
                painter.setBrush(Qt::black);
                painter.drawEllipse(m_margin + idx * m_cellSize - m_cellSize / 4, m_margin + jdx * m_cellSize - m_cellSize / 4, m_cellSize / 2, m_cellSize / 2);
            }
            else if (m_point[idx][jdx] == NPC)
            {
                /* 人机 */
                painter.setBrush(Qt::white);
                painter.drawEllipse(m_margin + idx * m_cellSize - m_cellSize / 4, m_margin + jdx * m_cellSize - m_cellSize / 4, m_cellSize / 2, m_cellSize / 2);
            }
        }
    }
}

/* 鼠标移动事件 */
void qipan::mouseMoveEvent(QMouseEvent * event)
{
    int row = (event->x() - m_margin + m_cellSize / 2) / m_cellSize;
    int col = (event->y() - m_margin + m_cellSize / 2) / m_cellSize;

    if ((row >= 0 && row < m_boardSize) && (col >= 0 && col < m_boardSize))
    {
        if (m_hoverRow != row || m_hoverCol != col)
        {
            m_hoverRow = row;
            m_hoverCol = col;
            m_isHoverFlag = true;

            /* 显示调用绘画事件 —— 更新画面 */
            update();
        }
    }
    else
    {
        if (m_isHoverFlag)
        {
            m_isHoverFlag = false;

            update();
        }
    }
}

/* 鼠标按压事件 */
void qipan::mousePressEvent(QMouseEvent * event)
{
    /* 棋盘的坐标 */
    int row = (event->x() - m_margin + m_cellSize / 2) / m_cellSize;
    int col = (event->y() - m_margin + m_cellSize / 2) / m_cellSize;

    /* 判断落点是否在棋盘内 */
    if ((row >= 0 && row < m_boardSize) && (col >= 0 && col < m_boardSize))
    {
        /* 发一个信号 */
        emit cellClicked(row, col);
    }
}

bool qipan::isCheckWin(int row, int col, Role role)
{
    /* 四个方向 */
    int directions[4][2] =
    {
        {1, 0},     //水平
        {0, 1},     //垂直
        {1, -1},    //左下右上
        {1, 1}      //右上左下
    };

    /* 遍历每个方向 */
    for (int direct = 0; direct < 4; direct++)
    {
        /* 初始计数 */
        int cnt = 1;

        /* 向一个方向探测 */
        for (int idx = 1; idx < 5; idx++)
        {
            int newRow = row + directions[direct][0] * idx;
            int newCol = col + directions[direct][1] * idx;

            if ((newRow >= 0 && newRow < m_boardSize) && (newCol >= 0 && newCol < m_boardSize) && m_point[newRow][newCol] == role)
            {
                cnt++;
            }
            else
            {
                break;
            }
        }

        /* 向反方向探测 */
        for (int idx = 1; idx < 5; idx++)
        {
            int newRow = row - directions[direct][0] * idx;
            int newCol = col - directions[direct][1] * idx;

            if ((newRow >= 0 && newRow < m_boardSize) && (newCol >= 0 && newCol < m_boardSize) && m_point[newRow][newCol] == role)
            {
                cnt++;
            }
            else
            {
                break;
            }
        }

        if (cnt >= 5)
        {
            return true;
        }
    }
    return false;
}

int qipan::getBoardSize()
{
    return m_boardSize;
}

int qipan::getPointVal(int row, int col)
{
    return m_point[row][col];
}

void qipan::setPointVal(int row, int col, Role role)
{
    m_point[row][col] = role;
}
